// @ts-nocheck
import React, { Component, useEffect, useMemo, useState } from 'react';
import { TreeSelect } from 'antd';
import { getTempData } from '@ey-utils/utils/services/get-temp-data';

const { TreeNode, SHOW_ALL } = TreeSelect;

interface TreeSelectProps {
  api?: {
    url: string;
    params?: {
      [key: string]: any;
    };
    type?: 'GET' | 'POST';
  }; // 接口参数
  data?: Array<any>; //显示的数据，格式 ：['选项一', '选项二'] 或 [{ name: '选项一', code: 1 }, { name: '选项二', code: 2 }];
  map?: {
    value: 'code' | string | number;
    text: 'name' | string;
  }; // 属性映射,未了匹配不同的业务
  treeCheckable?: boolean; // 是否显示 Checkbox
  multiple?: boolean; // 是否多选
  onlyLeaf?: boolean; // 只能选择叶子节点
  isFull?: boolean; // 是否拉取全量数据
  placeholder?: string;
  editable?: boolean;
  selectableKey?: string; // 判断是否可选择标识
  selectableCb?: (node: any) => boolean; // 判断是否可选择回调，优先级高于selectableKey
  splicingKey?: string; // 名称展示拼接字段标识
  showAll?: boolean; // 选中回填方式是否为显示所有节点（默认为SHOW_CHILD）
  treeCheckStrictly?: boolean; // 父子节点选中状态是否关联
  changeType?: '1' | '2'; // 1：返回 code 2：返回对象
  disabledNode?: {
    key: string;
    values: string[];
  };
  initDefaultValue?: boolean; // 是否需要默认值
  objCode?: string; // 默认值key 默认'code'
  changeSelect?: (v: any, node: any) => void;
  [key: string]: any;
}

export const BIZTreeSelect = (props: TreeSelectProps) => {
  const {
    api = {
      url: '',
      params: {},
      type: 'GET',
    },
    data,
    value,
    map = {
      value: 'code',
      text: 'name',
    },
    treeCheckable = false,
    multiple = false,
    onlyLeaf = false,
    isFull = true,
    onChange,
    placeholder,
    selectableKey,
    selectableCb,
    splicingKey,
    editable = true,
    disabled = false,
    showAll = true,
    treeCheckStrictly = false,
    changeType = '1',
    disabledNode,
    initDefaultValue = false,
    objCode = 'code',
  } = props;
  const [dataSource, setDataSource]: any = useState([]);
  useEffect(() => {
    if (api?.url) {
      getData({
        ...api,
        params: isFull
            ? {
              ...api.params,
              isFull: true,
            }
            : api.params,
      });
    }
  }, [JSON.stringify(api)]);

  const getData = async (api: any) => {
    try {
      const result: any = await getTempData(api);

      setDataSource(result);
      triggerDefaultInit(result);
      // 处理数据之后做初始化
    } catch (err) {
      console.warn(`treeSelect组件-getData发生错误:${err}`);
    }
  };

  const triggerDefaultInit = (dt: any) => {
    if (initDefaultValue === true && dt && dt?.length > 0 && dt[0][objCode]) {
      onChange(dt[0][objCode]);
    }
  };

  const changeSelect = (v: any, node: any, extra: any) => {
    props?.changeSelect?.(v, node);
  };

  const changeItem = (val: any, label: any, extra: any) => {
    let changeVal = val;

    if (val && treeCheckStrictly) {
      changeVal = val.map((item: any) => {
        return item.value;
      });
    }
    if (onChange) {
      if (changeType === '1') {
        onChange(changeVal, extra, label);
      }
      // 扩展一下字段
      else if(changeType === '2'){
        onChange(changeVal, {name: Array.isArray(label) ? label.join(''): label, code: Array.isArray(changeVal) ? changeVal.join(''): changeVal});
      }
      else {
        onChange(
            {
              code: changeVal,
              name: label[0],
            },
            changeVal,
            label,
        );
      }
    }
  };

  const renderNode = (datas: any[]) =>
      datas?.map((item: any) => {
        const props: any = {
          value: item[map?.value],
          title: splicingKey ? `${item[map?.text]}-${item[splicingKey]}` : item[map?.text],
          key: item[map?.value],
          ...item,
        };

        if (selectableKey && item[selectableKey] !== undefined) {
          props.selectable = item[selectableKey];
          props.disabled = !item[selectableKey];
        }

        if (disabledNode && disabledNode.key && disabledNode.values) {
          props.disabled = Array.isArray(disabledNode.values)
              ? disabledNode.values.includes(item[disabledNode.key])
              : props.disabled;
        }

        if (selectableCb) {
          props.selectable = selectableCb(item);
          props.disabled = !selectableCb(item);
        }

        if (onlyLeaf) {
          if (item.isLeaf || !item.children || item.children.length <= 0) {
            props.selectable = true;
            props.disabled = false;
          } else {
            props.selectable = false;
            props.disabled = true;
          }
        }

        return <TreeNode {...props}>{renderNode(item.children)}</TreeNode>;
      }) || '';
  const val = useMemo(() => {
    const initial = multiple || treeCheckable ? [] : '';
    if (!value) return initial;
    if (changeType === '1') {
      return value;
    } else if (typeof value === 'string') {
      return value;
    } else {
      return value?.code || initial;
    }
  }, [value]);
  return editable ? (
      <TreeSelect
          showSearch
          treeNodeFilterProp="title"
          style={{ width: '100%' }}
          value={val}
          dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
          placeholder={placeholder}
          allowClear
          onChange={changeItem}
          onSelect={changeSelect}
          disabled={disabled}
          treeCheckable={!!treeCheckable}
          multiple={multiple}
          showCheckedStrategy={showAll ? SHOW_ALL : undefined}
          treeCheckStrictly={treeCheckStrictly}
      >
        {renderNode(data && data.length ? data : dataSource || [])}
      </TreeSelect>
  ) : (
      <span>{value}</span>
  );
};

export default BIZTreeSelect;
